home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 002 / wsstrip.arc / WSSTRIP.C < prev    next >
Encoding:
C/C++ Source or Header  |  1987-01-26  |  11.9 KB  |  314 lines

  1.  
  2. /********************************************************************/
  3. /* CODE CONTAINED IN FILE NAMED:  WSSTRIP.C                         */
  4. /*                                                                  */
  5. /* DATE FINISHED 1/26/87                 BY: Tadas Osmolskis        */
  6. /*                                                                  */
  7. /* PURPOSE: Cleans up Wordstar files. Strips high bits, gets rid    */
  8. /*          of formatting special characters, and deletes lines     */
  9. /*          that begin with periods (dot commands). Provides simple */
  10. /*          minded line, word and sentence counts.                  */
  11. /*                                                                  */
  12. /* COMPILER USED: Datalight C, version 2.12                         */
  13. /*                                                                  */
  14. /* OTHER FILES:   HGETSTR.C  - function which gets a string from    */
  15. /*                             the console, without a carriage      */
  16. /*                             return at the end. From Hunt,        */
  17. /*                             The C Toolbox (Addison-Wesley,1985)  */
  18. /*                                                                  */
  19. /* TESTING CONDUCTED: Tested on heavily formatted WS file, on files */
  20. /*                    with embedded dot commands, (including those  */
  21. /*                    with dot commands at beginning of file), and  */
  22. /*                    on file containing only an EOF. All input     */
  23. /*                    modes tested.                                 */
  24. /*                                                                  */
  25. /* KNOWN LIMITATIONS: Not the fastest program known to humankind.   */
  26. /*                                                                  */
  27. /* OTHER COMMENTS: Should be fairly portable to any compiler that   */
  28. /*                 supports floats & bit manipulations.             */
  29. /*                                                                  */
  30. /********************************************************************/
  31. #include <stdio.h>
  32. #include <ctype.h>
  33.  
  34. #define BOOL  int
  35. #define FALSE 0
  36. #define TRUE  1
  37.  
  38. #define SENTEND (curchar=='.' || curchar=='!' || curchar=='?')
  39. #define WHITESP (curchar==' ' || curchar=='\t' || curchar=='\n')
  40. #define WORDEND (curchar==' ' || curchar==',' || curchar ==';' ||\
  41.                 curchar==':' || curchar==')' )
  42.  
  43.  
  44. #define CR 0x0D
  45. #define LF 0x0A
  46. #define MASK 0x7F       /* Produces bit pattern which, when logically ANDed
  47.                            with a character-holding int, strips the high bit */
  48.  
  49. #define DEBUG 0
  50.  
  51. /* MS-DOS C compilers don't return the program name as argv[0] */
  52. /* Therefore, we have to provide the name if we want to use it */
  53.  
  54. char  pgmname[]="wsstrip"; /* Used by get_file_names()      */
  55.  
  56.  
  57. main (argc, argv)
  58. int argc;
  59. char *argv[];
  60.  
  61. {          /** STARTBODY main **/
  62.  
  63. int curchar;
  64. int get_file_names();
  65. BOOL inword = FALSE;
  66. BOOL is_space();
  67. FILE  *infile;
  68. FILE  *outfile;
  69. FILE  *file_array[2];
  70. long count_words();
  71. long numchars = 0L;
  72. long numlines = 0L;
  73. long numsent = 0L;
  74. long numwords = 0L;
  75. char  temp;
  76.  
  77.  
  78. /** If the user didn't specify any file names on the command line, **/
  79. /** the program will prompt for an input and output file name.     **/
  80. /** If only one file name is given on the command line, output will **/
  81. /** be routed to stdout, so that it can be redirected. If both file **/
  82. /** names are on the command line, the first name is the input file **/
  83. /** name, and the second is the output file name.                   **/
  84.  
  85. if (argc < 2)
  86. {
  87.    get_file_names(file_array,pgmname);
  88.    infile = file_array[0];
  89.    outfile = file_array[1];
  90. }
  91. else
  92.    if (argc == 2)
  93.      {
  94.      infile = fopen(argv[1],"r");
  95.      if (! infile )
  96.         {
  97.         fprintf(stderr,"\nThe file named %s doesn't seem to be ",argv[1]);
  98.         fprintf(stderr,"on this disk or directory.\nYou must be ");
  99.         fprintf(stderr,"on the same drive/directory as the file ");
  100.         fprintf(stderr,"that you want to process.\nCheck the directory ");
  101.         fprintf(stderr,"and make sure that you are where you want to ");
  102.         fprintf(stderr,"be,\nand that you spelled the file name correctly.");
  103.         exit();
  104.         }
  105.      outfile = stdout; /* to the tube, unless you tell it otherwise */
  106.      }
  107.    else
  108.       {
  109.      infile = fopen(argv[1],"r");
  110.      if (! infile )
  111.         {
  112.         fprintf(stderr,"\nThe file named %s doesn't seem to be ",argv[1]);
  113.         fprintf(stderr,"on this disk or directory.\nYou must be ");
  114.         fprintf(stderr,"on the same drive and directory as the file ");
  115.         fprintf(stderr,"that you want to process.\nCheck the directory ");
  116.         fprintf(stderr,"and make sure that you are where you want to ");
  117.         fprintf(stderr,"be,\nand that you spelled the file name correctly.");
  118.         exit();
  119.         }
  120.       if (outfile = fopen(argv[2],"r"))
  121.          {
  122.          fprintf(stderr,"\nThe file you want to write to, %s, ",argv[2]);
  123.          fprintf(stderr,"already exists. Pick a \ndifferent name and ");
  124.          fprintf(stderr,"run %s again",pgmname);
  125.          fclose(outfile);
  126.          exit();
  127.          }
  128.       else
  129.          outfile = fopen(argv[2],"w");
  130.       }
  131.  
  132. /* Test the first character to see if it's a Wordstar "dot command" */
  133. /* The general idea is that temp holds the first character read     */
  134. /* until the first line is read (a "state variable") if the first   */
  135. /* character is a period (which means it's a dot command). Note     */
  136. /* that, after the first line is read and thrown away, the program  */
  137. /* tests the first char of the next line as well. (Wordstar dot     */
  138. /* commands tend to cluster at the top of files).                   */
  139. /* If it isn't a dot command, then we put back the character &      */
  140. /* pretend nothing happened.                                        */
  141.  
  142. temp = getc(infile);
  143. while (temp == '.')  /* If it's a dot command ... */
  144.       {
  145.       curchar = temp;   /* initialize curchar to something we know */
  146.                         /* isn't a "\n"                            */
  147.  
  148.       while (curchar != '\n')  /* while we're still in the dot command */
  149.                                /* line                                 */
  150.          {
  151.          curchar = getc(infile);    /*read it and throw it out */
  152.          }
  153.       temp =getc(infile); /* Maybe the first char in the next line */
  154.                           /* is a dot command as well ....         */
  155.       }
  156.  
  157. ungetc(temp, infile);   /* We can start processing the file now */
  158.  
  159. curchar = getc(infile);     /*Priming read. Datalight C V2.12 didn't    */
  160.                             /* like the read in the following "while"   */
  161.  
  162. /** Read the file, strip the high bits, and count characters, sentences, **/
  163. /** lines, and words.                                                    **/
  164.  
  165. while (curchar  != EOF)
  166.       {
  167.       curchar &= MASK;          /* Strip the high bit. No more     */
  168.                                 /* wordstar funny characters       */
  169. /* Check for "soft carriage returns"                               */
  170.  
  171.  
  172. if (curchar == CR)
  173.         if ((temp = getc(infile)) == LF)        /* try it */
  174.                 curchar = '\n';
  175.         else
  176.                 ungetc (temp, infile);          /* put it back if not */
  177.  
  178. /* Now, make sure it's a print character or a legitimate control character */
  179. /* and not a happy face or some other weirdness caused by Wordstar format  */
  180. /* codes.                                                                  */
  181.  
  182.       if ( ( (curchar >= ' ') && (curchar <= '~') )
  183.       || (curchar == '\r')
  184.       || (curchar == '\t')
  185.       || (curchar == '\n')
  186.       || (curchar == '\f'))
  187.       putc(curchar,outfile);
  188.  
  189.  
  190.       if (!WHITESP)           numchars++; /* Count characters... */
  191.  
  192.       if (SENTEND)            numsent++;  /* sentences...        */
  193.  
  194.       if (curchar == '\n')
  195.          {
  196.          numlines++;            /* lines...            */
  197.  
  198.          /* and while we're here, let's kill off lines with Wordstar */
  199.          /* dot commands...                                          */
  200.  
  201.          temp = getc(infile);
  202.          if (temp == '.')
  203.             {
  204.             while (curchar = getc(infile) != '\n')
  205.             ;   /*throw it out */
  206.             }
  207.          else
  208.             {
  209.             ungetc(temp,infile);  /* It's not a dot in col 1, so put it */
  210.             }                     /* back ...                           */
  211.          } /* end of the "\n" processing; back to counting   */
  212.  
  213.       /* ...words, which are not as simple-minded as the above three. */
  214.  
  215.        if ( (is_space (curchar)) || (WORDEND) ) /* We're clearly not */
  216.                 inword = FALSE;                 /* within a word ... */
  217.        else
  218.                 if (!inword) /* If we're not already in a word; ie.,
  219.                                 if this is the first character */
  220.                 {
  221.                 inword = TRUE; /* let's make it TRUE */
  222.                 numwords++;   /* and increment the counter */
  223.                 }
  224.  
  225.       curchar = getc(infile);   /* Read the next character */
  226.  
  227.       }                     /* End of "while not EOF" loop*/
  228.  
  229.  
  230.  
  231. /** Print the count of characters, sentences, lines and words, and **/
  232. /** compute and print the average number of characters per word.   **/
  233.  
  234.  
  235. printf ("\n\t\t\tNumber of characters: %ld\n",
  236.              numchars);
  237.  
  238. printf ("\t\t\tNumber of lines: %ld\n",
  239.              numlines);
  240.  
  241. printf ("\t\t\tNumber of words: %ld\n",
  242.              numwords);
  243.  
  244. printf ("\t\t\tNumber of sentences: %ld\n",
  245.              numsent);
  246.  
  247. if (numwords > 0L) /* Dividing by zero isn't such a wonderful idea...  */
  248.                    /* Also, note the casts to type float in the printf */
  249.                    /* statement                                        */
  250.    {
  251.    printf ("\t\t\tAverage characters per word: %4.1f\n",
  252.                 (float)numchars/(float)numwords);
  253.    }
  254. else
  255.    {
  256.    fprintf(stderr,"Your file, %s, doesn't have\n any words in it. ",argv[1]);
  257.    fprintf(stderr,"Make sure you're working with the right file");
  258.    }
  259.  
  260.  
  261. /** Now, the cleanup, which for this program, is to close the files. **/
  262.  
  263. fclose(infile);
  264. fclose(outfile);
  265.  
  266. }               /* ENDMAIN */
  267.  
  268. BOOL    is_space(ch)
  269.         char    ch;
  270.         {
  271.         return ((ch == ' '|| ch == '\t' || ch == '\n') ? TRUE : FALSE);
  272.         }
  273.  
  274.  
  275. int get_file_names(file_array,program_name)
  276. FILE * file_array[2];
  277. char * program_name;  /* MS-DOS doesn't return the program name as argv[0] */
  278.                       /* 8 characters is the maximum length for a filename */
  279.                       /* under MS-DOS. */
  280. {
  281. char  in_file_name[13], out_file_name[13];
  282. int getstr(); /* Returns the count of characters in the string */
  283. int x;        /* Throwaway to receive value returned by getstr() */
  284.  
  285. printf ("You haven't given  %s an input and output file name\n", program_name);
  286. printf ("What is the name of the file you want to process?: ");
  287. x = getstr(in_file_name,12);
  288. if (! (file_array[0] = fopen(in_file_name,"r")))
  289.    {
  290.    fprintf(stderr,"\nThe file named %s doesn't seem to be ",in_file_name);
  291.    fprintf(stderr,"on this disk or directory.\nYou must be ");
  292.    fprintf(stderr,"on the same drive / directory as the file ");
  293.    fprintf(stderr,"that you're looking for.\nCheck the directory ");
  294.    fprintf(stderr,"and make sure that you are where you want to ");
  295.    fprintf(stderr,"be,\nand that you spelled the file name correctly.");
  296.    exit();
  297.    }
  298.  
  299.  
  300. printf ("What name do you want the output file to have?: ");
  301. x = getstr(out_file_name,12);
  302. if (file_array[1] = fopen(out_file_name,"r"))
  303.     {
  304.     fprintf(stderr,"\nThe file you want to write to, %s, ",out_file_name);
  305.     fprintf(stderr,"already exists. Pick a different name and ");
  306.     fprintf(stderr,"run %s again",program_name);
  307.     fclose(file_array[1]);
  308.     exit();
  309.     }
  310. else
  311.     file_array[1] = fopen(out_file_name,"w");
  312.  
  313. }   /*** END OF get_file_names()    ***/
  314.